package io.xjar.zip;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.List;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;

/**
 * @author chen_lei
 * @date 2021/5/12 15:42
 */
public class GZIPUtil {

    /**
     * 压缩tar.gz
     *
     * @param targetName 目标文件夹文件全名
     */
    public static String compressGZ(List<File> sources, String targetName) {
        return packGZ(packTar(sources, targetName));
    }

    /**
     * @param sources 要打包的原文件数组
     * @return File    返回打包后的文件
     */
    private static File packTar(List<File> sources, String targetName) {
        if (targetName == null || "".equals(targetName)) {
            return null;
        }

        try {
            String target = targetName.replace(".gz", "");
            FileOutputStream out = new FileOutputStream(target);
            TarArchiveOutputStream os = new TarArchiveOutputStream(out);
            for (File file : sources) {
                TarArchiveEntry tarArchiveEntry = new TarArchiveEntry(file.getName());
                tarArchiveEntry.setSize(file.length());
                tarArchiveEntry.setMode(tarArchiveEntry.getMode() | 777);

                os.putArchiveEntry(tarArchiveEntry);

                IOUtils.copy(new FileInputStream(file), os);
                os.closeArchiveEntry();
            }

            os.flush();
            os.close();

            return new File(target);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * 将文件用gzip压缩
     *
     * @param source 需要压缩的文件Tar
     * @return File    返回压缩后的文件路径
     */
    private static String packGZ(File source) {
        try {
            String target = URLDecoder.decode(source.getAbsolutePath() + ".gz", "utf-8");

            FileInputStream in = new FileInputStream(source);
            GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(target));

            byte[] array = new byte[1024];
            int number = -1;
            while ((number = in.read(array, 0, array.length)) != -1) {
                out.write(array, 0, number);
            }

            out.flush();
            out.close();
            in.close();

            source.delete();

            return target;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

    }

}
